package com.sz.app.oss.api.logistics.bill;

import com.sz.app.oss.constants.MessagesCodes;
import com.sz.app.oss.constants.Permissions;
import com.sz.biz.app.web.BaseController;
import com.sz.biz.logistics.bill.dto.BillingDeleteDto;
import com.sz.common.base.dto.CommonModel;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.utils.StringUtils;
import com.sz.biz.logistics.bill.entity.BillingStatus;
import com.sz.biz.logistics.bill.entity.BillingTaskStatus;
import com.sz.biz.logistics.bill.service.BillingOrderRelService;
import com.sz.biz.logistics.bill.service.BillingService;
import com.sz.biz.logistics.bill.dto.BillingUrlDto;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.List;
import java.util.Map;

/**
 * Function: 账单管理 <br>
 * Author: jifeixing <br>
 * Date: 2017-05-17 14:18:00
 */
@RestController
@RequestMapping("${api}/biz/financial/{type}")
@Api(description = " ", tags = "041、账单管理")
public class BillingController extends BaseController {

    @Autowired
    private BillingService billingService;
    @Autowired
    private BillingOrderRelService billingOrderRelService;

    /**
     * 根据账单号删除账单
     *
     * @param billingDeleteDto
     * @return
     */
    @ApiOperation(value = "根据账单号删除账单", notes = "根据账单号删除账单<br>权限：" + Permissions.BIZ_MGT_BASE_FINANCIAL)
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "type", value = "账单号", required = true, dataType = "string", paramType = "path"),
                    @ApiImplicitParam(name = "billingDeleteDto", value = "重试的任务编码列表", required = true, dataType = "BillingDeleteDto", paramType = "body")
            })
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_FINANCIAL)
    public ResultDto batchDeleteBillingByNos(@PathVariable String type, @RequestBody BillingDeleteDto billingDeleteDto) {
        billingService.batchdeleteByNos(billingDeleteDto.getBillNos(),type,billingDeleteDto.getCustomers());
        return getDeleteSuccessDto(MessagesCodes.MODULE_FINANCIAL);
    }

    /**
     * 获取账单下所有订单
     *
     * @param billNo
     * @return
     */
    @ApiOperation(value = "获取账单下所有订单", notes = "获取账单下所有订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "模糊查询参数", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "billNo", value = "账单号", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "订单类型", required = false, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "orderNo", value = "订单号", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "waybillNo", value = "运单号", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "serviceUid", value = "服务Uid", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "productUid", value = "产品Uid", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "customerId", value = "账号名", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "startEffectTime", value = "起始出帐时间(yyyy-MM-dd HH:mm:ss)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endEffectTime", value = "结束出帐时间(yyyy-MM-dd HH:mm:ss)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小，max2000", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序的字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "asc", value = "排序方式", dataType = "boolean", paramType = "query", defaultValue = "true")})
    @RequestMapping(value = "/orders", method = {RequestMethod.GET})
    public ResultDto getOrdersByBillNo(@RequestParam(required = false) String q,
                                       @RequestParam(required = true) String billNo,
                                       @PathVariable String type,
                                       @RequestParam(required = false) String orderNo,
                                       @RequestParam(required = false) String waybillNo,
                                       @RequestParam(required = false) String serviceUid,
                                       @RequestParam(required = false) String productUid,
                                       @RequestParam(required = false) Integer customerId,
                                       @RequestParam(required = false) String startEffectTime,
                                       @RequestParam(required = false) String endEffectTime,
                                       @RequestParam(required = false, defaultValue = "1") int pageIndex,
                                       @RequestParam(required = false, defaultValue = "10") int pageSize,
                                       @RequestParam(required = false) String sort,
                                       @RequestParam(required = false, defaultValue = "true") Boolean asc) {
        q = StringUtils.replaceSqlPattern(q);
        QueryParams params = new QueryParams(pageSize, pageIndex, q, sort, asc);
        params.put("billNo", billNo);
        params.put("orderNo", orderNo);
        params.put("waybillNo", waybillNo);
        params.put("serviceUid", serviceUid);
        params.put("productUid", productUid);
        params.put("customerId", customerId);
        params.put("startEffectTime", billingService.populateTime(startEffectTime));
        params.put("endEffectTime", billingService.populateTime(endEffectTime));
        params.put("type", type);
        return billingOrderRelService.getOrdersByBillNo(params);
    }

    /**
     * 所有账单状态
     *
     * @return
     */
    @ApiOperation(value = "所有账单状态", notes = "所有账单状态")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "isAudit", value = "待审核状态： \r\n0: 返回全部状态； \r\n1： 返回待审核以上状态", defaultValue = "0", required = false, dataType = "String", paramType = "query")})
    @RequestMapping(value = "/billingStatus", method = RequestMethod.GET)
    public ResultDto getBillingStatus(@RequestParam(required = false, defaultValue = "0") String isAudit) {
        List<CommonModel> list = billingService.getBillingStatus(isAudit);
        ResultDto result = new ResultDto();
        result.setData(list);
        return result;
    }

    /**
     * 分页查询账单列表
     */
    @ApiOperation(value = "搜索账单", notes = "搜索账单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "模糊查询参数", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "billNo", value = "账单号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "账单类型", dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "waybillNo", value = "订单号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "includeAllAudit", value = "当status为AUDITING时，返回AUDITING以上的状态", dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "customerId", value = "账户，多个逗号分隔", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "startEffectTime", value = "起始出帐时间(yyyy-MM-dd HH:mm:ss)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endEffectTime", value = "结束出帐时间(yyyy-MM-dd HH:mm:ss)", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小，max2000", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序的字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "asc", value = "排序方式", dataType = "boolean", paramType = "query", defaultValue = "true")})
    @RequestMapping(value = "/list", method = {RequestMethod.GET})
    public ResultDto findBillingList(@RequestParam(required = false) String q,
                                     @RequestParam(required = false) String billNo,
                                     @PathVariable String type,
                                     @RequestParam(required = false) String waybillNo,
                                     @RequestParam(required = false) BillingStatus status,
                                     @RequestParam(required = false) boolean includeAllAudit,
                                     @RequestParam(required = false) String customerId,
                                     @RequestParam(required = false) String startEffectTime,
                                     @RequestParam(required = false) String endEffectTime,
                                     @RequestParam(required = false, defaultValue = "1") int pageIndex,
                                     @RequestParam(required = false, defaultValue = "10") int pageSize,
                                     @RequestParam(required = false) String sort,
                                     @RequestParam(required = false, defaultValue = "true") Boolean asc) {
        q = StringUtils.replaceSqlPattern(q);
        QueryParams params = new QueryParams(pageSize, pageIndex, q, sort, asc);
        params.put("startEffectTime", billingService.populateTime(startEffectTime));
        params.put("endEffectTime", billingService.populateTime(endEffectTime));
        params.put("billNo", billNo);
        params.put("type", type);
        params.put("waybillNo", waybillNo);
        if(!StringUtils.isEmpty(customerId)){
            String[] customerIsArray = customerId.split(",");
            params.put("customerIds", customerIsArray);
        }

        params.put("status", status);
        params.put("includeAllAudit", includeAllAudit);
        params.put("taskStatus", BillingTaskStatus.COMPLETED);
        return billingService.findByFilter(params);
    }

    /**
     * 提交审核
     */
    @ApiOperation(value = "提交审核", notes = "提交审核-权限<br>" + Permissions.BIZ_MGT_BASE_FINANCIAL)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "账单类型", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "billNos", value = "账单号集合", dataType = "List", paramType = "body", required = true)
    })
    @RequestMapping(value = "/submit", method = {RequestMethod.POST})
    @RequiresPermissions(value = {Permissions.BIZ_MGT_BASE_FINANCIAL})
    public ResultDto submit(@PathVariable String type,@RequestBody List<String> billNos) throws ParseException {
        billingService.submit(billNos,type);
        return getSubmitSuccessDto(MessagesCodes.MODULE_FINANCIAL);
    }

    /**
     * 审核账单
     */
    @ApiOperation(value = "审核账单,已付款", notes = "审核账单,已付款-<br>" + Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "账单类型", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "map", value = "billNos, \r\ntype(CHARGEOFF: 审核通过；DRAFT： 打回草稿； PAID： 已付款), \r\nmsg", required = true, dataType = "Map", paramType = "body")
    })
    @RequestMapping(value = "/audit", method = {RequestMethod.POST})
    @RequiresPermissions(value = {Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL})
    public ResultDto audit(@PathVariable String type,@RequestBody Map<String, Object> map) throws ParseException {
        BillingStatus statusTo = billingService.audit(map,type);
        switch (statusTo) {
            case DRAFT:
                return getRejectSuccessDto();
            case CHARGEOFF:
                return getChargeoffSuccessDto(MessagesCodes.MODULE_FINANCIAL);
            case PAID:
                return getOperatePaidSuccessDto(MessagesCodes.MODULE_FINANCIAL);
            default:
                return getOperationSuccessDto(MessagesCodes.MODULE_FINANCIAL);
        }
    }

    /**
     * 价格调整-只有待审核状态下可以调整价格
     * @param billingDto
     * @return
     * @throws ParseException
     */
    @ApiOperation(value = "价格调整", notes = "价格调整-<br>" + Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "账单类型", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "billingDto", value = "billNo, \r\nadjustmentTypeCode(UPPER: 上调；DOWN： 下调), " +
                    "\r\nadjustmentValue, adjustmentUnit(1: %; 2: 金额), adjustmentRemark", required = true, dataType = "BillingDto", paramType = "body")
    })
    @RequestMapping(value = "/adjustment", method = {RequestMethod.POST})
    @RequiresPermissions(value = {Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL})
    public ResultDto adjustment(@PathVariable String type,@RequestBody Map<String, String> billingDto) throws ParseException {
        billingService.adjustment(billingDto,type);
        return getBillingAdjustmentSuccessDto(MessagesCodes.MODULE_FINANCIAL);
    }

    /**
     * 所有价格调整类型： 上调和下调
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "账单类型", required = true, dataType = "string", paramType = "path")
    })
    @RequestMapping(value = "/adjustmentType", method = RequestMethod.GET)
    @ApiOperation(value = "所有价格调整类型", notes = "所有价格调整类型")
    public ResultDto getAdjustmentType(@PathVariable String type) {
        List<CommonModel> list = billingService.getAdjustmentType();
        ResultDto result = new ResultDto();
        result.setData(list);
        return result;
    }

    /**
     * 账单导出
     */
    @ApiOperation(value = "账单导出", notes = "账单导出-权限<br>" + Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "账单类型", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "billNos", value = "账单号集合", dataType = "List", paramType = "body", required = true)
    })
    @RequestMapping(value = "/export", method = {RequestMethod.POST})
    @RequiresPermissions(value = {Permissions.BIZ_MGT_BASE_FINANCIAL_APPROVAL})
    public ResultDto export(@PathVariable String type,@RequestBody List<String> billNos) throws ParseException {
    	List<BillingUrlDto> list=billingService.export(billNos,type);
        ResultDto result = new ResultDto();
        result.setData(list);
        return result;
    }

}
